/*
 * RootControl.java
 *
 * Created on 2004/04/26 +0900
 *
 * $Revision: 59 $
 * $Date: 2008-12-28 19:22:21 +0000 (Sun, 28 Dec 2008) $
 */

package org.gikolet.framework.ui;

import java.util.Vector;

import org.gikolet.framework.Toolkit;
import org.gikolet.framework.util.Assert;

/**
 * @author Tetsutaro (latest modification by $Author: tetsutaro.ss $)
 * @version $Revision: 59 $ $Date: 2008-12-28 19:22:21 +0000 (Sun, 28 Dec 2008) $
 */
public class RootControl extends Panel {
    private Widget focus;
    private MenuItem _menuItem;
    private Vector children;

    RootControl(RootControl root) {
	this(root, false);
    }

    RootControl(RootControl root, boolean focusable) {
	super(focusable, true);

	if (root == null) {
	    setBackColor(new Color(0xECE4D8));
	    setForeColor(Color.BLACK);
	    setFont(Toolkit.getDisplay().getFontProvider().getDefaultFont());
	} else {
	    setParent(root);
	}

	setVisible(false);
    }

    public final void setMenuItem(MenuItem menuItem) {
	_menuItem = menuItem;
	Display display = getDisplay();
	if (display != null) {
	    if (display.getCurrentWindow() == this) {
		display.setMenuItemNavi(menuItem);
	    }
	}
    }

    protected void setParent(Widget parent) {
	if (parent != null) {
	    Assert.isFalse(parent instanceof RootControl);
	}

	super.setParent(parent);
    }

    public final MenuItem getMenuItem() {
	return _menuItem;
    }

    public void pack() {
	setSize(getPreferredSize(DEFAULT_LAYOUT, DEFAULT_LAYOUT));
    }

    public void setBackColor(Color color) {
	if (color == null) {
	    if (getParent() == null) {
		color = new Color(0xECE4D8);
	    }
	}
	Color setBackColor = getSetBackColor();
	if (setBackColor != color) {
	    super.setBackColor(color);
	    if (children != null) {
		for (int i = 0; i < children.size(); i++) {
		    Widget c = (Widget) children.elementAt(i);
		    c.firePropertyChanged(PROPERTY_BACK_COLOR);
		    fireChildBackColorChanged(c);
		}
	    }
	}
    }

    public void setFont(Font font) {
	Font setFont = getSetFont();
	if (font == setFont) {
	    return;
	}
	if (font == null) {
	    if (getParent() == null) {
		font = Toolkit.getDisplay().getFontProvider().getDefaultFont();
	    }
	}

	if (setFont != font) {
	    super.setFont(font);
	    if (children != null) {
		for (int i = 0; i < children.size(); i++) {
		    Widget c = (Widget) children.elementAt(i);
		    c.firePropertyChanged(PROPERTY_FONT);
		    fireChildFontChanged(c);
		}
	    }
	}
    }

    public void setForeColor(Color color) {
	if (color == null) {
	    if (getParent() == null) {
		color = Color.BLACK;
	    }
	}
	Color setForeColor = getSetForeColor();
	if (setForeColor != color) {
	    super.setForeColor(color);
	    if (children != null) {
		for (int i = 0; i < children.size(); i++) {
		    Widget c = (Widget) children.elementAt(i);
		    c.firePropertyChanged(PROPERTY_FORE_COLOR);
		    fireChildFontChanged(c);
		}
	    }
	}
    }

    public boolean isCurrentRootControl() {
	Display display = getDisplay();
	return (display != null && display.getCurrentWindow() == this);
    }

    void setFocus(Widget control) {
	setFocusCore(control);

	Display display = getDisplay();
	if (display != null) {
	    if (control != null && isCurrentRootControl()) {
		display.setPopupMenuItemNavi(control.getPopupMenuItem());
	    } else {
		display.setPopupMenuItemNavi(null);
	    }
	}
    }

    void setFocusCore(Widget control) {
	this.focus = control;
    }

    Widget getFocus() {
	return this.focus;
    }

    private void addChildRootControl(RootControl root) {
	if (children == null) {
	    children = new Vector();
	}
	if (!children.contains(root)) {
	    if (getFont() != null && !root.isSetFont()) {
		root.firePropertyChanged(PROPERTY_FONT);
		fireChildFontChanged(root);
	    }
	    if (getBackColor() != null && !root.isSetBackColor()) {
		root.firePropertyChanged(PROPERTY_BACK_COLOR);
		fireChildBackColorChanged(root);
	    }
	    if (getForeColor() != null && !root.isSetForeColor()) {
		root.firePropertyChanged(PROPERTY_FORE_COLOR);
		fireChildForeColorChanged(root);
	    }
	    children.addElement(root);
	}
    }

    private void removeChildRootControl(RootControl root) {
	if (children != null && children.contains(root)) {
	    if (getFont() != null && !root.isSetFont()) {
		root.firePropertyChanged(PROPERTY_FONT);
		fireChildFontChanged(root);
	    }
	    if (getBackColor() != null && !root.isSetBackColor()) {
		root.firePropertyChanged(PROPERTY_BACK_COLOR);
		fireChildBackColorChanged(root);
	    }
	    if (getForeColor() != null && !root.isSetForeColor()) {
		root.firePropertyChanged(PROPERTY_FORE_COLOR);
		fireChildForeColorChanged(root);
	    }
	    children.removeElement(root);
	}
    }

    public void repaint(int x, int y, int width, int height, boolean direct) {
	getDisplay().paint(x, y, width, height, direct);
    }

    /**
     * @see org.gikolet.framework.ui.Container#firePropertyChanged(java.lang.String)
     */
    protected void firePropertyChanged(String propertyName) {
	if (PROPERTY_VISIBLE.equals(propertyName)) {
	    Container parent = getParent();
	    if (parent != null) {
		RootControl rootParent = (RootControl) parent;
		if (isVisible()) {
		    rootParent.addChildRootControl(this);
		} else {
		    rootParent.removeChildRootControl(this);
		}
	    }/*
	      * if (visible) { if (getFocus() == null) { transferFocusForward();
	      * } }
	      */
	}
	super.firePropertyChanged(propertyName);
    }
}
